﻿using debugger;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.IO.Ports;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public class Base : Form
    {

        [DllImport("my_jtag_atlantic.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern int open_jtag();

        [DllImport("my_jtag_atlantic.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern void close_jtag();

        [DllImport("my_jtag_atlantic.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern int write_jtag(int len, byte[] buff, int index);

        //[DllImport("my_jtag_atlantic.dll", CallingConvention = CallingConvention.Cdecl)]
        //public static extern void flush_jtag();

        [DllImport("my_jtag_atlantic.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern int read_jtag(int len, byte[] buff, int index);


        byte[] data = new byte[5];
        public bool connect()
        {
            int ret = open_jtag();
            if (ret != 0)
            {
                {
                    byte[] buff = new byte[256 * 1024];
                    int remain = buff.Length;
                    int index = 0;
                    Stopwatch sw = new Stopwatch();
                    sw.Start();
                    while (true)
                    {
                        int len = write_jtag(remain, buff, index);
                        index += len;
                        remain -= len;
                        if (remain == 0)
                        {
                            break;
                        }
                        if (sw.ElapsedMilliseconds > 1000000)
                        {
                            throw new Exception();
                        }
                    }
                    sw.Stop();
                    Console.WriteLine(sw.ElapsedMilliseconds);
                }
                {
                    byte[] buff = new byte[256 * 1024];
                    int remain = buff.Length;
                    int index = 0;
                    Stopwatch sw = new Stopwatch();
                    sw.Start();
                    while (true)
                    {
                        int len = write_jtag(remain, buff, index);
                        index += len;
                        remain -= len;
                        if (remain == 0)
                        {
                            break;
                        }
                        if (sw.ElapsedMilliseconds > 1000000)
                        {
                            throw new Exception();
                        }
                    }
                    sw.Stop();
                    Console.WriteLine(sw.ElapsedMilliseconds);
                }
                {
                    byte[] buff = new byte[256*1024];//256k/2s 128kb/s
                    int remain = buff.Length;
                    int index = 0;
                    Stopwatch sw = new Stopwatch();
                    sw.Start();
                    while (true)
                    {
                        int len = read_jtag(remain, buff, index);
                        index += len;
                        remain -= len;
                        if (remain == 0)
                        {
                            break;
                        }
                        if (sw.ElapsedMilliseconds > 1000000)
                        {
                            throw new Exception();
                        }
                    }
                    sw.Stop();
                    Console.WriteLine(sw.ElapsedMilliseconds);

                }

                byte[] data = new byte[2048];

                sendCmd(Form1.SET_DEBUG_ADDRESS, 0);
                uint ret1 = sendCmdRet1(Form1.MEM_TRANS_READ, 2048 + 0);
                if (ret1 != 123)
                {
                    throw new Exception();
                }

                receive(data);









                return true;
            }
            else
            {
                return false;
            }
        }
        private uint readFromPort4()
        {
            byte[] data = new byte[4];
            Stopwatch sw = new Stopwatch();
            sw.Start();
            while (true)
            {
                int ret = read_jtag(4, data, 0);
                if (ret == 4)
                {
                    break;
                }
                if (ret != 0)
                {
                    throw new Exception();
                }
                if (sw.ElapsedMilliseconds > 1000000)
                {
                    throw new Exception();
                }
            }
            sw.Stop();
            Console.WriteLine(sw.ElapsedMilliseconds);

            uint temp = 0;
            temp |= data[0];
            temp |= (uint)(data[1] << 8);
            temp |= (uint)(data[2] << 16);
            temp |= (uint)(data[3] << 24);
            return temp;
        }

        public uint sendCmdRet4(byte cmd, uint? udata = null)
        {
            sendCmd(cmd, udata);
            uint val = 0;
            val = readFromPort4();
            return val;
        }
        private uint readFromPort1()
        {
            byte[] data = new byte[1];
            Stopwatch sw = new Stopwatch();
            sw.Start();
            while (true)
            {
                int ret = read_jtag(1, data, 0);
                if (ret == 1)
                {
                    break;
                }
                if (sw.ElapsedMilliseconds > 1000000) {
                    throw new Exception();
                }
            }
            sw.Stop();
            Console.WriteLine(sw.ElapsedMilliseconds);
            uint temp = 0;
            temp |= data[0];
            return temp;
        }

        public uint sendCmdRet1(byte cmd, uint? udata = null)
        {
            sendCmd(cmd, udata);
            uint val = 0;
            val = readFromPort1();
            return val;
        }

        public void sendCmd(byte cmd, uint? udata = null)
        {
            byte[] buff = new byte[4];
            buff[0] = cmd;
            write_jtag(1, buff, 0);
            long bb = 0;
            if ((cmd & 0x80) != 0 && udata != null)
            {
                buff[0] = (byte)(udata & 0xFF);
                buff[1] = (byte)((udata >> 8) & 0xFF);
                buff[2] = (byte)((udata >> 16) & 0xFF);
                buff[3] = (byte)((udata >> 24) & 0xFF);
                write_jtag(4, buff, 0);
            }
            //flush_jtag();
        }

        public void receive(byte[] data)//read
        {
            if (data.Length == 2048)
            {
                byte[] buff = new byte[1];
                buff[0] = 0x36;
                write_jtag(1, buff, 0);
                int remain = 2048;
                int index = 0;
                Stopwatch sw = new Stopwatch();
                sw.Start();
                while (true)
                {
                    int len = read_jtag(remain, data, index);
                    index += len;
                    remain -= len;
                    if (remain == 0)
                    {
                        break;
                    }
                    if (sw.ElapsedMilliseconds > 1000000)
                    {
                        throw new Exception();
                    }
                }
                sw.Stop();
                Console.WriteLine(sw.ElapsedMilliseconds);

            }
        }
        public void send(byte[] data)//write
        {
            if (data.Length == 2048)
            {
                byte[] buff = new byte[1];
                buff[0] = 0xF0;
                write_jtag(1, buff, 0);
                write_jtag(2048, data, 0);
            }
        }

    }
}
